package com.enation.app.javashop.core.shop.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.enation.app.javashop.core.geo.service.TencentManager;
import com.enation.app.javashop.core.goods.model.dos.CategoryDO;
import com.enation.app.javashop.core.goods.model.dos.GoodsSkuDO;
import com.enation.app.javashop.core.goods.model.dos.TagsDO;
import com.enation.app.javashop.core.goods.model.vo.GoodsSkuVO;
import com.enation.app.javashop.core.member.model.dos.MemberComment;
import com.enation.app.javashop.core.member.service.MemberCollectionShopManager;
import com.enation.app.javashop.core.member.service.MemberManager;
import com.enation.app.javashop.core.shop.model.dos.ShipTemplateDO;
import com.enation.app.javashop.core.shop.model.dos.TemplateTimeSetting;
import com.enation.app.javashop.core.shop.model.dto.NearbyShopDTO;
import com.enation.app.javashop.core.shop.model.dto.QueryNearbyShopDTO;
import com.enation.app.javashop.core.shop.model.enums.ShopTemplateTypeEnum;
import com.enation.app.javashop.core.shop.model.dto.NearbyShopCatGoodsDTO;
import com.enation.app.javashop.core.shop.model.vo.NearbyShopCatGoodsVO;
import com.enation.app.javashop.core.shop.model.vo.NearbyShopDetailsVO;
import com.enation.app.javashop.core.shop.model.vo.NearbyShopVO;
import com.enation.app.javashop.core.shop.service.NearbyShopManager;
import com.enation.app.javashop.core.statistics.StatisticsException;
import com.enation.app.javashop.core.trade.cart.model.enums.CheckedWay;
import com.enation.app.javashop.core.trade.cart.model.vo.CartSkuVO;
import com.enation.app.javashop.core.trade.cart.model.vo.CartVO;
import com.enation.app.javashop.core.trade.cart.model.vo.CartView;
import com.enation.app.javashop.core.trade.cart.service.CartReadManager;
import com.enation.app.javashop.framework.context.UserContext;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.database.Page;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.util.DateUtil;
import com.enation.app.javashop.framework.util.StringUtil;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: zhou
 * @Date: 2021/3/10
 * @Description: 返回附近店铺列表
 */
@Service
@Log4j
public class NearbyShopManagerImpl implements NearbyShopManager {
    @Autowired
    @Qualifier("systemDaoSupport")
    private DaoSupport daoSupport;

    @Autowired
    private TencentManager tencentManager;

    @Autowired
    private MemberManager memberManager;

    @Autowired
    private MemberCollectionShopManager memberCollectionShopManager;

    @Autowired
    private CartReadManager cartReadManager;

    /**
     * 查询附近店铺列表
     *
     * @return
     */
    @Override
    public Page nearbyShopList(QueryNearbyShopDTO queryNearbyShopDTO) {
        String shopIdsString = queryNearbyShopDTO.getShopId();
        if (StringUtil.isEmpty(shopIdsString)) {
            throw new StatisticsException("请求参数错误！");
        }

        List<String> shopIds = Arrays.asList(shopIdsString.split(","));
        Integer pageNo = queryNearbyShopDTO.getPageNo() == null ? 1 : queryNearbyShopDTO.getPageNo();
        Integer pageSize = queryNearbyShopDTO.getPageSize() == null ? 5 : queryNearbyShopDTO.getPageSize();
        Integer arrSize = shopIds.size();

        List<NearbyShopVO> nearbyShopVOList = new ArrayList<>();
        int a = arrSize % pageSize > 0 ? arrSize / pageSize + 1 : arrSize / pageSize;
        for (int i = pageNo; pageNo <= a; pageNo++) {
            int startLength = (pageNo - 1) * pageSize;
            int endLength = pageNo * pageSize > arrSize ? arrSize : pageNo * pageSize;
            List<String> shopId = shopIds.subList(startLength, endLength);
            // 每次查询5个店铺，每家店铺显示30个商品
            nearbyShopVOList = this.getNearbyShopList(StringUtil.listToString(shopId, ","), queryNearbyShopDTO.getLocationLat(), queryNearbyShopDTO.getLocationLng(), queryNearbyShopDTO.getOpenId(), 1, 10);
            if (!CollectionUtils.isEmpty(nearbyShopVOList)) {
                break;
            }

        }

        Page page = new Page();
        page.setData(nearbyShopVOList);
        page.setDataTotal(arrSize.longValue());
        page.setPageNo(pageNo);
        page.setPageSize(queryNearbyShopDTO.getPageSize());
        return page;
    }

    @Override
    public NearbyShopDetailsVO nearbyShopDetails(QueryNearbyShopDTO queryNearbyShopDTO) {
        String shopDetailsSql = "SELECT s.shop_id seller_id,s.shop_name AS seller_name,s.shop_lat,s.shop_lng,d.open_time," +
                "d.link_phone,d.shop_logo,d.shop_service_credit,d.goods_management_category,d.shop_province,d.shop_county," +
                "d.shop_town,d.shop_add,t.min_ship_price,t.base_ship_price FROM es_shop s \n" +
                "LEFT JOIN es_shop_detail d ON s.shop_id=d.shop_id\n" +
                "LEFT JOIN es_ship_template t ON s.shop_id=t.seller_id\n" +
                "WHERE s.shop_id=? AND t.template_type='TONGCHENG'";


        String promotionSql = "SELECT * FROM (\n" +
                "(SELECT CASE promotion_type WHEN 'FULL_DISCOUNT' THEN title WHEN 'POINT' THEN '积分活动' \n" +
                "WHEN 'MINUS' THEN '单品立减' WHEN 'EXCHANGE' THEN '积分换购' WHEN 'HALF_PRICE' THEN '第二件半价' \n" +
                "WHEN 'SHETUAN' THEN '社区团购' WHEN 'NEWCOMER' THEN '新人购'  END  as promotion_name FROM es_promotion_goods WHERE seller_id=? \n" +
                "AND start_time<=? AND end_time>=? GROUP BY promotion_type\n" +
                ") UNION ALL\n" +
                "(SELECT '限时秒杀' as promotion_name FROM es_seckill  WHERE seller_ids=? AND seckill_status = 'RELEASE' \n" +
                "AND start_day>=? \n" +
                ") UNION ALL\n" +
                "(SELECT '多人拼团' as promotion_name FROM es_pintuan WHERE seller_id=? AND `status`='UNDERWAY' \n" +
                "AND start_time>=? AND end_time>=?\n" +
                "))tmp";

        Integer sellerId = Integer.parseInt(queryNearbyShopDTO.getShopId());
        Long nowTime = DateUtil.getDateline();

        // 查询店铺信息
        NearbyShopDetailsVO shopDetail = this.daoSupport.queryForObject(shopDetailsSql, NearbyShopDetailsVO.class, sellerId);
        if (shopDetail == null) {
            throw new ServiceException("500", "店铺不存在");
        }

        // 查询活动信息
        List<Map> promotionList = new ArrayList<>();
        List<Map> promotionNameList = this.daoSupport.queryForList(promotionSql, sellerId, nowTime, nowTime, sellerId, nowTime, sellerId, nowTime, nowTime);
        if (!CollectionUtils.isEmpty(promotionNameList)) {
            for (Map map : promotionNameList) {
                if ("新人特惠".equals(map.get("promotion_name").toString())) {
                    map.put("color", 1);
                    promotionList.add(map);
                } else if ("限时秒杀".equals(map.get("promotion_name").toString())) {
                    map.put("color", 2);
                    promotionList.add(map);
                } else {
                    map.put("color", 3);
                    promotionList.add(map);
                }
            }
            shopDetail.setPromotionList(promotionList);
        }

        // 查询店铺分类信息
        String categorySql = "SELECT `name` FROM es_category WHERE category_id IN (" + shopDetail.getGoodsManagementCategory() + ")";
        if (!StringUtil.isEmpty(shopDetail.getGoodsManagementCategory())) {
            List<CategoryDO> categoryList = this.daoSupport.queryForList(categorySql, CategoryDO.class);
            if (!CollectionUtils.isEmpty(categoryList)) {
                List<String> categoryNames = categoryList.stream().map(item -> item.getName()).collect(Collectors.toList());
                shopDetail.setCategoryNameList(categoryNames);
            }
        }

        // 查询有商品的店铺分组
        String shopCatSql = "SELECT cat1.shop_cat_id as one_cat_id,cat1.shop_cat_name as one_cat_name,tmp.* FROM (\n" +
                "SELECT cat.shop_cat_id as two_cat_id,cat.shop_cat_name as two_cat_name,IF(cat.shop_cat_pid=0,cat.shop_cat_id,cat.shop_cat_pid) as two_cat_pid,g.goods_name,g.small,g.price,g.mktprice\n" +
                " FROM es_goods g\n" +
                "LEFT JOIN es_shop_cat cat ON g.shop_cat_id=cat.shop_cat_id\n" +
                "WHERE cat.shop_id= ? and cat.disable = 1 AND g.market_enable=1 AND g.is_auth IN (1,2) \n" +
                ") tmp LEFT JOIN es_shop_cat cat1 ON tmp.two_cat_pid=cat1.shop_cat_id\n" +
                "GROUP BY one_cat_id";
        List<NearbyShopCatGoodsDTO> shopCatDOList = this.daoSupport.queryForList(shopCatSql, NearbyShopCatGoodsDTO.class, sellerId);
        shopDetail.setShopCatDOList(shopCatDOList);

        //查询评价
        String contentSql = "SELECT * FROM es_member_comment WHERE content !='此商品默认好评' AND content !='此评论默认好评！！'\n" +
                " AND seller_id = " + sellerId + " GROUP BY seller_id ";
        MemberComment memberComment = this.daoSupport.queryForObject(contentSql, MemberComment.class);
        if (memberComment != null) {
            shopDetail.setContent(memberComment.getContent());
        }


        // 查询配送时间和配送距离
        Map<String, Double> timeAndDistance = this.getTimeAndDistance(shopDetail, queryNearbyShopDTO);
        shopDetail.setShipTime(timeAndDistance.get("shipTime").intValue());
        shopDetail.setShopDistance(timeAndDistance.get("distanceKm"));
        shopDetail.setBaseShipPrice(timeAndDistance.get("baseShipPrice"));
        shopDetail.setMinShipPrice(timeAndDistance.get("minShipPrice"));

        // 判断用户是否已经收藏了该店铺
        shopDetail.setIsCollection(memberCollectionShopManager.isCollection(sellerId));

        return shopDetail;
    }

    @Override
    public List<NearbyShopCatGoodsVO> getGoodsList(Integer sellerId, Integer shopCatId) {
        if (sellerId == null) {
            throw new ServiceException("500", "请求参数错误");
        }

        // 1、如果没有传shopCatId，默认查询第一个一级分组ID
        String shopCatIdString;
        if (shopCatId == null) {
            shopCatIdString = "(SELECT cat1.shop_cat_id  FROM (\n" +
                    "                SELECT cat.shop_cat_id as two_cat_id,cat.shop_cat_name as two_cat_name,IF(cat.shop_cat_pid=0,cat.shop_cat_id,cat.shop_cat_pid) as two_cat_pid,g.goods_name,g.small,g.price,g.mktprice\n" +
                    "                 FROM es_goods g\n" +
                    "                LEFT JOIN es_shop_cat cat ON g.shop_cat_id=cat.shop_cat_id\n" +
                    "                WHERE cat.shop_id= " + sellerId + " and cat.disable = 1 AND g.market_enable=1 AND g.is_auth IN (1,2) \n" +
                    "                ) tmp LEFT JOIN es_shop_cat cat1 ON tmp.two_cat_pid=cat1.shop_cat_id\n" +
                    "                GROUP BY shop_cat_id LIMIT 1)";
        } else {
            shopCatIdString = shopCatId.toString();
        }

        // 2、根据一级分组ID查询所有子分组及一级分组ID
        String sql="SELECT * FROM (\n" +
                "(SELECT replace (left(IF(c1.cat_path_name = NULL,c.cat_path,c1.cat_path),\n" +
                "                CHAR_LENGTH(IF(c1.cat_path_name = NULL,c.cat_path,c1.cat_path)) - 1),'|',',') shop_cat_id FROM es_shop_cat c\n" +
                "                LEFT JOIN es_shop_cat c1 ON c.shop_cat_id=c1.shop_cat_pid\n" +
                "                WHERE c.shop_cat_id="+shopCatIdString+")\n" +
                "UNION ALL \n" +
                "(SELECT replace (left(IF(c1.cat_path_name = NULL,c.cat_path,c1.cat_path),\n" +
                "                CHAR_LENGTH(IF(c1.cat_path_name = NULL,c.cat_path,c1.cat_path)) - 1),'|',',') shop_cat_id FROM es_shop_cat c\n" +
                "                LEFT JOIN es_shop_cat c1 ON c.shop_cat_id=c1.shop_cat_id\n" +
                "                WHERE c.shop_cat_id="+shopCatIdString+"))tmp";
        List<Map> catList = this.daoSupport.queryForList(sql);

        String shopCatIds = shopCatId == null ? "" : shopCatId.toString();
        if (!CollectionUtils.isEmpty(catList)) {
            for (Map map : catList) {
                if (map.get("shop_cat_id") != null) {
                    shopCatIds = shopCatIds.concat(",");
                    shopCatIds = shopCatIds.concat(map.get("shop_cat_id").toString());
                }
            }
            if (shopCatIds.startsWith(",")) {
                shopCatIds = shopCatIds.substring(1);
            }
        }

        if (StringUtil.isEmpty(shopCatIds)) {
            throw new ServiceException("500", "店铺主页查询商品时分组ID为空");
        }
        // 获取所有商品分组ID，并去重
        shopCatIds = StringUtil.listToString(Arrays.asList(shopCatIds.split(",")).stream().distinct().collect(Collectors.toList()), ",");

        // 3、根据分组ID查询商品
        String goodsSql = "SELECT cat1.shop_cat_id as one_cat_id,cat1.shop_cat_name as one_cat_name,tmp.*,sku.*,t.* FROM (\n" +
                "SELECT cat.shop_cat_id as two_cat_id,cat.shop_cat_name as two_cat_name,IF(cat.shop_cat_pid=0,cat.shop_cat_id,cat.shop_cat_pid) as two_cat_pid\n" +
                ",g.goods_id,g.small FROM es_goods g\n" +
                "LEFT JOIN es_shop_cat cat ON g.shop_cat_id=cat.shop_cat_id\n" +
                "WHERE cat.shop_id= ? and cat.disable = 1 AND g.market_enable=1 AND g.is_auth IN (1,2) AND cat.shop_cat_id in (" + shopCatIds + ")\n" +
                ") tmp LEFT JOIN es_shop_cat cat1 ON tmp.two_cat_pid=cat1.shop_cat_id\n" +
                "LEFT JOIN es_goods_sku sku ON tmp.goods_id=sku.goods_id\n" +
                "LEFT JOIN es_tag_goods tg ON tg.goods_id=tmp.goods_id\n" +
                "LEFT JOIN es_tags t ON tg.tag_id=t.tag_id";
        List<NearbyShopCatGoodsDTO> nearbyShopCatGoodsDTOList = this.daoSupport.queryForList(goodsSql, NearbyShopCatGoodsDTO.class, sellerId);

        // 最终返回的商品列表
        List<NearbyShopCatGoodsVO> catGoodsVOList = new ArrayList<>();

        // 如果查询出来的商品列表为空，则直接返回空数组
        if (CollectionUtils.isEmpty(nearbyShopCatGoodsDTOList)) {
            return catGoodsVOList;
        }

        // 如果用户登录之后，获取购物车商品列表
        Map<Integer, List<CartSkuVO>> cartSkuVOMap = null;
        if (UserContext.getBuyer() != null) {
            CartView cartView = this.cartReadManager.getCheckedItems(CheckedWay.valueOf("CART"), sellerId);
            List<CartVO> cartVOList = cartView.getCartList();
            if (!CollectionUtils.isEmpty(cartVOList)) {
                List<CartSkuVO> cartSkuVOList = cartVOList.get(0).getSkuList();
                if (!CollectionUtils.isEmpty(cartSkuVOList)) {
                    cartSkuVOMap = cartSkuVOList.stream().collect(Collectors.groupingBy(CartSkuVO::getGoodsId, Collectors.toList()));
                }

            }
        }


        Map<Integer, List<NearbyShopCatGoodsDTO>> goodsMap = nearbyShopCatGoodsDTOList.stream().collect(Collectors.groupingBy(GoodsSkuDO::getGoodsId, Collectors.toList()));
        for (Integer key : goodsMap.keySet()) {
            NearbyShopCatGoodsVO goodsVO = new NearbyShopCatGoodsVO();
            List<NearbyShopCatGoodsDTO> goodsDetailList = goodsMap.get(key);

            NearbyShopCatGoodsDTO goodsDTO = goodsDetailList.get(0);
            BeanUtils.copyProperties(goodsDTO, goodsVO);


            // 加入购物车的商品
            List<CartSkuVO> cartSkuVOList = new ArrayList<>();
            // 所有加购商品的数量之和
            Integer num = 0;
            if (cartSkuVOMap != null && !CollectionUtils.isEmpty(cartSkuVOMap.get(goodsDTO.getGoodsId()))) {
                cartSkuVOList = cartSkuVOMap.get(goodsDTO.getGoodsId());
                for (CartSkuVO sku : cartSkuVOList) {
                    num = num + sku.getNum();
                }
            }
            goodsVO.setCartSkuNum(num);
            goodsVO.setCartSkuList(cartSkuVOList);

            // 封装商品的SKU列表
            List<GoodsSkuVO> skuList = new ArrayList<>();
            // 封装商品的标签列表
            List<TagsDO> tagList = new ArrayList<>();
            for (NearbyShopCatGoodsDTO goods : goodsDetailList) {
                GoodsSkuVO skuDO = new GoodsSkuVO();
                BeanUtils.copyProperties(goods, skuDO);
                if (skuDO != null && skuDO.getSkuId() != null) {
                    int cartNum=0;
                    if(!CollectionUtils.isEmpty(cartSkuVOList)){
                        List<CartSkuVO> skuVOS=cartSkuVOList.stream().filter(sku->sku.getSkuId().equals(skuDO.getSkuId())).collect(Collectors.toList());
                        if(!CollectionUtils.isEmpty(skuVOS)){
                            cartNum=skuVOS.get(0).getNum();
                        }

                    }
                    skuDO.setAddCartNum(cartNum);
                    skuList.add(skuDO);
                }

                TagsDO tagsDO = new TagsDO();
                BeanUtils.copyProperties(goods, tagsDO);
                if (tagsDO != null && tagsDO.getTagId() != null) {
                    tagList.add(tagsDO);
                }

            }
            goodsVO.setSkuList(skuList);
            goodsVO.setTagList(tagList);




            catGoodsVOList.add(goodsVO);
        }

        return catGoodsVOList;
    }

    private List<NearbyShopVO> getNearbyShopList(String shopIdsString, Double locationLat, Double locationLng, String openId, Integer pageNum, Integer pageSize) {
        if (StringUtil.isEmpty(shopIdsString) || locationLat == null || locationLng == null) {
            throw new StatisticsException("请求参数错误！");
        }

        // 查询商品信息
        long nowTime = DateUtil.getDateline();
        if (pageNum == null) {
            pageNum = 1;
        }
        if (pageSize == null) {
            pageSize = 10;
        }

        String[] shopIds = shopIdsString.split(",");
        // 保存店铺的前30个商品（因为每个店铺都需要展示前30个，所以只能一个个店铺查询
        Map<String, List<NearbyShopDTO>> nearbyShopDTOMap = new HashMap<>();
        // 所有店铺的商品ID
        List<Integer> goodsIds = new ArrayList<>();
        for (String shopId : shopIds) {
            List<NearbyShopDTO> nearbyShopDTOList = this.getGoodsList(shopId, nowTime, openId, pageNum, pageSize);
            if (!CollectionUtils.isEmpty(nearbyShopDTOList)) {
                nearbyShopDTOMap.put(shopId, nearbyShopDTOList);
                goodsIds.addAll(nearbyShopDTOList.stream().map(NearbyShopDTO::getGoodsId).distinct().collect(Collectors.toList()));
            }

        }
        if (CollectionUtils.isEmpty(goodsIds)) {
            // throw new StatisticsException("店铺没有商品");
            return null;
        }
        goodsIds = goodsIds.stream().distinct().collect(Collectors.toList());
        String goodsIdsString = StringUtil.listToString(goodsIds, ",");
        String goodsTagSql = "SELECT DISTINCT t.* FROM es_tag_goods  tg LEFT JOIN es_tags t ON tg.tag_id=t.tag_id \n" +
                "WHERE tg.goods_id in (" + goodsIdsString + ") AND t.seller_id in (" + shopIdsString + ")";
        List<TagsDO> tagsDOList = this.daoSupport.queryForList(goodsTagSql, TagsDO.class);
        Map<Integer, List<TagsDO>> tagDOMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(tagsDOList)) {
            tagDOMap = tagsDOList.stream().collect(Collectors.groupingBy(TagsDO::getSellerId, Collectors.toList()));
        }

        //查询评价
        String contentSql = "SELECT * FROM es_member_comment WHERE content !='此商品默认好评' AND content !='此评论默认好评！！'\n" +
                "AND goods_id in (" + goodsIdsString + ") AND seller_id in (" + shopIdsString + ") GROUP BY seller_id ";
        List<MemberComment> memberCommentList = this.daoSupport.queryForList(contentSql, MemberComment.class);
        Map<Integer, String> contentMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(memberCommentList)) {
            contentMap = memberCommentList.stream().collect(Collectors.toMap(MemberComment::getSellerId, MemberComment::getContent));
        }

        // 查询配送模板，计算配送时间
        String shipTempleteSql = "SELECT * FROM es_ship_template WHERE seller_id in (" + shopIdsString + ") AND template_type='TONGCHENG' ";
        List<ShipTemplateDO> shipTemplateDOList = this.daoSupport.queryForList(shipTempleteSql, ShipTemplateDO.class);
        Map<Integer, List<ShipTemplateDO>> shipTemplateDOMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(shipTemplateDOList)) {
            shipTemplateDOMap = shipTemplateDOList.stream().collect(Collectors.groupingBy(ShipTemplateDO::getSellerId, Collectors.toList()));
        }

        // 返回店铺列表数据
        List<NearbyShopVO> nearbyShopVOList = new ArrayList<>();
        for (String shopId : shopIds) {
            List<NearbyShopDTO> nearbyShopDTOList = nearbyShopDTOMap.get(shopId);
            if (CollectionUtils.isEmpty(nearbyShopDTOList)) {
                continue;
            }
            NearbyShopVO nearbyShopVO = new NearbyShopVO(nearbyShopDTOList);
            nearbyShopVO.setGoodsTags(tagDOMap.get(shopId));
            nearbyShopVO.setContent(contentMap.get(shopId));

            // 计算距离
            double distanceKm = 0D;
            NearbyShopDTO nearbyShopDTO = nearbyShopDTOList.get(0);
            if (nearbyShopDTO.getShopLat() != null && nearbyShopDTO.getShopLng() != null) {
                Double distanceM = tencentManager.countDrivingDistance((locationLat + "," + locationLng), nearbyShopDTO.getShopLat() + "," + nearbyShopDTO.getShopLng());
                if (distanceM != null && distanceM != 0) {
                    distanceKm = new BigDecimal(distanceM / 1000).setScale(1, BigDecimal.ROUND_DOWN).doubleValue();
                }
            }
            nearbyShopVO.setShopDistance(distanceKm);

            // 计算配送时间 单位是分钟
            int shipTime = 0;
            ShipTemplateDO shipTemplateDO = this.getTemplate(shipTemplateDOMap.get(Integer.parseInt(shopId)));
            if (shipTemplateDO != null && !StringUtil.isEmpty(shipTemplateDO.getTimeSetting())) {
                TemplateTimeSetting templateTimeSetting
                        = JSON.parseObject(shipTemplateDO.getTimeSetting(), new TypeReference<TemplateTimeSetting>() {
                });
                // 如果配送时间配置的时根据距离计算时间的话，计算配送时间
                if (templateTimeSetting.getTimeType() == 1) {
                    shipTime = calculateTimeByDistance(templateTimeSetting, BigDecimal.valueOf(distanceKm));
                }

                nearbyShopVO.setBaseShipPrice(shipTemplateDO.getBaseShipPrice() == null ? 0 : shipTemplateDO.getBaseShipPrice().doubleValue());
                nearbyShopVO.setMinShipPrice(shipTemplateDO.getMinShipPrice() == null ? 0 : shipTemplateDO.getMinShipPrice().doubleValue());
            }
            nearbyShopVO.setShipTime(shipTime);

            nearbyShopVOList.add(nearbyShopVO);
        }

        return nearbyShopVOList;

    }

    private Map<String, Double> getTimeAndDistance(NearbyShopDetailsVO shopDetail, QueryNearbyShopDTO queryNearbyShopDTO) {

        Integer sellerId = shopDetail.getSellerId();

        // 查询配送模板，计算配送时间
        String shipTempleteSql = "SELECT * FROM es_ship_template WHERE seller_id = " + sellerId + " AND template_type='TONGCHENG' ";
        List<ShipTemplateDO> shipTemplateDOList = this.daoSupport.queryForList(shipTempleteSql, ShipTemplateDO.class);
        Map<Integer, List<ShipTemplateDO>> shipTemplateDOMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(shipTemplateDOList)) {
            shipTemplateDOMap = shipTemplateDOList.stream().collect(Collectors.groupingBy(ShipTemplateDO::getSellerId, Collectors.toList()));
        }

        // 计算距离
        double distanceKm = 0D;
        if (shopDetail.getShopLat() != null && shopDetail.getShopLng() != null) {
            Double distanceM = tencentManager.countDrivingDistance((queryNearbyShopDTO.getLocationLat() + "," + queryNearbyShopDTO.getLocationLng()), shopDetail.getShopLat() + "," + shopDetail.getShopLng());
            if (distanceM != null && distanceM != 0) {
                distanceKm = new BigDecimal(distanceM / 1000).setScale(1, BigDecimal.ROUND_DOWN).doubleValue();
            }
        }

        Double baseShipPrice = 0D;
        Double minShipPrice = 0D;

        // 计算配送时间 单位是分钟
        int shipTime = 0;
        ShipTemplateDO shipTemplateDO = this.getTemplate(shipTemplateDOMap.get(sellerId));
        if (shipTemplateDO != null && !StringUtil.isEmpty(shipTemplateDO.getTimeSetting())) {
            TemplateTimeSetting templateTimeSetting
                    = JSON.parseObject(shipTemplateDO.getTimeSetting(), new TypeReference<TemplateTimeSetting>() {
            });
            // 如果配送时间配置的时根据距离计算时间的话，计算配送时间
            if (templateTimeSetting.getTimeType() == 1) {
                shipTime = calculateTimeByDistance(templateTimeSetting, BigDecimal.valueOf(distanceKm));
            }

            baseShipPrice = shipTemplateDO.getBaseShipPrice().doubleValue();
            minShipPrice = shipTemplateDO.getMinShipPrice().doubleValue();
        }

        Map<String, Double> map = new HashMap<>();
        map.put("distanceKm", distanceKm);
        map.put("shipTime", new Double(shipTime));
        map.put("baseShipPrice", baseShipPrice);
        map.put("minShipPrice", minShipPrice);
        return map;
    }


    // 获取配送模板
    private ShipTemplateDO getTemplate(List<ShipTemplateDO> shipTemplates) {
        ShipTemplateDO shipTemplateDO = new ShipTemplateDO();

        if (CollectionUtils.isEmpty(shipTemplates)) {
            return shipTemplateDO;
        }

        // 获取同城配送模板
        List<ShipTemplateDO> tongchengTemps = shipTemplates.stream().filter(temp -> ShopTemplateTypeEnum.TONGCHENG.value().equals(temp.getTemplateType())).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(tongchengTemps)) {
            shipTemplateDO = tongchengTemps.get(0);
        }

        return shipTemplateDO;
    }

    // 分页获取商品列表
    private List<NearbyShopDTO> getGoodsList(String shopIdsString, long nowTime, String openId, Integer pageNum, Integer pageSize) {

        String sql = "SELECT c.`name` AS two_category_name, tmp.* FROM (\n" +
                "SELECT c.parent_id AS three_parent_id, c.`name` AS three_category_name,detail.shop_service_credit,detail.open_time,detail.business_status,detail.shop_lat,detail.shop_lng,CONCAT(detail.shop_province,detail.shop_city,detail.shop_county,detail.shop_town,detail.shop_add) as shop_address,detail.shop_logo,shop.shop_name seller_name, tmp1.*\n" +
                "FROM (\n" +
                "(SELECT pg.activity_id,0 AS required_num,pg.promotion_type,pg.title,pg.price,pg.product_id as sku_id,g.goods_id,g.goods_name,g.mktprice,g.thumbnail,g.seller_id,g.template_id,g.category_id FROM es_promotion_goods pg\n" +
                "LEFT JOIN es_goods g ON pg.goods_id=g.goods_id\n" +
                "WHERE pg.seller_id = " + shopIdsString + " AND pg.start_time <=" + nowTime + " AND pg.end_time >=" + nowTime + ")\n" +
                "UNION ALL\n" +
                "(SELECT pt.promotion_id as activity_id ,pt.required_num,'PINTUAN' as promotion_type,pt.promotion_name as title,ptg.sales_price as price,ptg.sku_id,ptg.goods_id ,ptg.goods_name,ptg.origin_price as mktprice,ptg.thumbnail,ptg.seller_id ,g.template_id,g.category_id  FROM es_pintuan pt\n" +
                "LEFT JOIN es_pintuan_goods ptg ON ptg.pintuan_id=pt.promotion_id\n" +
                "LEFT JOIN es_goods g ON ptg.goods_id=g.goods_id\n" +
                "WHERE pt.seller_id = " + shopIdsString + " AND  pt.start_time <=" + nowTime + " AND pt.end_time >=" + nowTime + " AND  ptg.pintuan_id IS NOT NULL )\n" +
                "UNION ALL\n" +
                "(SELECT NULL as activity_id,0 AS required_num,'NORMAL' as promotion_type,NULL as title,g.price,sku.sku_id,g.goods_id,g.goods_name,g.mktprice,g.thumbnail,g.seller_id,g.template_id,g.category_id\n" +
                "FROM es_goods g LEFT JOIN es_goods_sku sku ON g.goods_id=sku.goods_id WHERE g.seller_id = " + shopIdsString + " AND g.market_enable=1 AND g.is_auth=1 ORDER BY g.create_time DESC )\n" +
                ")tmp1\n" +
                "LEFT JOIN es_category c ON tmp1.category_id = c.category_id\n" +
                "LEFT JOIN es_shop_detail detail ON tmp1.seller_id=detail.shop_id\n" +
                "LEFT JOIN es_shop shop ON tmp1.seller_id=shop.shop_id\n" +
                "WHERE shop.shop_disable='OPEN'" +
                "order by field(promotion_type,'NORMAL','SHETUAN','FULL_DISCOUNT','SECKILL','PINTUAN','NEWCOMER') DESC\n" +
                ") tmp\n" +
                "LEFT JOIN es_category c ON c.category_id = tmp.three_parent_id\n" +
                "WHERE c.parent_id != 0 ";
        // 如果已经登陆且不是新人的时候，过滤新人购活动商品
        if (!StringUtil.isEmpty(openId) && !memberManager.selNewUserByOpenId(openId)) {
            sql = sql + " AND tmp.promotion_type !='NEWCOMER' ";
        }
        sql = sql + "LIMIT ?,?";

        if (pageNum == null) {
            pageNum = 1;
        }
        if (pageSize == null) {
            pageSize = 10;
        }

        List<NearbyShopDTO> nearbyShopDTOList = this.daoSupport.queryForList(sql, NearbyShopDTO.class, (pageNum - 1) * pageSize, pageSize);

        if (!CollectionUtils.isEmpty(nearbyShopDTOList)) {
            try {
                // 获取店铺营业时间  没有营业时间 则不显示店铺
                String openTime = nearbyShopDTOList.get(0).getOpenTime();
                Integer businessStatus = nearbyShopDTOList.get(0).getBusinessStatus();
                if(businessStatus !=null && businessStatus == 1 && StringUtil.notEmpty(openTime)){
                    JSONArray openTimeJsonArray = JSON.parseArray(openTime);
                    SimpleDateFormat format = new SimpleDateFormat("HH:mm");
                    long nowDate = format.parse(format.format(new Date())).getTime();
                    // 查看店铺营业时间 在该时间是否满足
                    boolean flag = false;
                    for (Object openTimes : openTimeJsonArray) {
                        JSONObject openTimeJson = JSON.parseObject(openTimes.toString());
                        String startTime = openTimeJson.getString("start_time");
                        long startTimeDate = format.parse(startTime).getTime();
                        String endTime = openTimeJson.getString("end_time");
                        long endTimeDate = format.parse(endTime).getTime();
                        if (startTimeDate <= nowDate && endTimeDate >= nowDate) {
                            flag = true;
                            break;
                        }
                    }
                    if (flag) {
                        nearbyShopDTOList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getGoodsId()))), ArrayList::new));
                    } else {
                        nearbyShopDTOList = new ArrayList<>();
                    }
                } else {
                    nearbyShopDTOList = new ArrayList<>();
                }

            } catch (ParseException e) {
                log.error("时间转换错误---" + e);
            }
        }
        return nearbyShopDTOList;
    }

    // 获取商品总数
    private Integer getGoodsCount(String shopIdsString, long nowTime, String openId) {

        String sql = "SELECT COUNT(tmp.goods_id) FROM (\n" +
                "SELECT c.parent_id AS three_parent_id, c.`name` AS three_category_name,detail.shop_service_credit,detail.shop_lat,detail.shop_lng,shop.shop_name seller_name, tmp1.*\n" +
                "FROM (\n" +
                "(SELECT pg.activity_id,pg.promotion_type,pg.title,pg.price,pg.product_id as sku_id,g.goods_id,g.goods_name,g.mktprice,g.thumbnail,g.seller_id,g.template_id,g.category_id FROM es_promotion_goods pg\n" +
                "LEFT JOIN es_goods g ON pg.goods_id=g.goods_id\n" +
                "WHERE pg.seller_id in (" + shopIdsString + ") AND pg.start_time <=" + nowTime + " AND pg.end_time >=" + nowTime + ")\n" +
                "UNION ALL\n" +
                "(SELECT pt.promotion_id as activity_id ,'PINTUAN' as promotion_type,pt.promotion_name as title,ptg.sales_price as price,ptg.sku_id,ptg.goods_id ,ptg.goods_name,ptg.origin_price as mktprice,ptg.thumbnail,ptg.seller_id ,g.template_id,g.category_id  FROM es_pintuan pt\n" +
                "LEFT JOIN es_pintuan_goods ptg ON ptg.pintuan_id=pt.promotion_id\n" +
                "LEFT JOIN es_goods g ON ptg.goods_id=g.goods_id\n" +
                "WHERE pt.seller_id in (" + shopIdsString + ") AND  pt.start_time <=" + nowTime + " AND pt.end_time >=" + nowTime + " AND  ptg.pintuan_id IS NOT NULL )\n" +
                "UNION ALL\n" +
                "(SELECT NULL as activity_id,'NORMAL' as promotion_type,NULL as title,g.price,sku.sku_id,g.goods_id,g.goods_name,g.mktprice,g.thumbnail,g.seller_id,g.template_id,g.category_id\n" +
                "FROM es_goods g LEFT JOIN es_goods_sku sku ON g.goods_id=sku.goods_id WHERE g.seller_id in (" + shopIdsString + ") AND g.market_enable=1 AND g.is_auth=1 )\n" +
                ")tmp1\n" +
                "LEFT JOIN es_category c ON tmp1.category_id = c.category_id\n" +
                "LEFT JOIN es_shop_detail detail ON tmp1.seller_id=detail.shop_id\n" +
                "LEFT JOIN es_shop shop ON tmp1.seller_id=shop.shop_id\n" +
                "WHERE shop.shop_disable='OPEN' AND detail.open_start_time <= DATE_FORMAT(FROM_UNIXTIME(" + nowTime + "),'%H:%i') AND detail.open_end_time >= DATE_FORMAT(FROM_UNIXTIME(" + nowTime + "),'%H:%i') \n" +
                "order by field(promotion_type,'NORMAL','SHETUAN','FULL_DISCOUNT','SECKILL','PINTUAN','NEWCOMER') DESC\n" +
                ") tmp\n" +
                "LEFT JOIN es_category c ON c.category_id = tmp.three_parent_id\n" +
                "WHERE c.parent_id != 0 ";

        // 如果已经登陆且不是新人的时候，过滤新人购活动商品
        if (!StringUtil.isEmpty(openId) && !memberManager.selNewUserByOpenId(openId)) {
            sql = sql + " AND tmp.promotion_type !='NEWCOMER' ";
        }

        return this.daoSupport.queryForInt(sql);

    }

    /**
     * 根据距离---配送时间
     *
     * @param templateTimeSetting
     * @param distanceTarget
     * @return
     */
    private int calculateTimeByDistance(TemplateTimeSetting templateTimeSetting, BigDecimal distanceTarget) {
        Integer shipTime = 0;
        if (templateTimeSetting.getBaseDistance().compareTo(distanceTarget) < 0) {
            BigDecimal extraTime = distanceTarget.subtract(templateTimeSetting.getBaseDistance())
                    .divide(templateTimeSetting.getUnitDistance(), 3, BigDecimal.ROUND_HALF_DOWN)
                    .multiply(templateTimeSetting.getUnitTime());
            shipTime = templateTimeSetting.getBaseTime().add(extraTime).intValue();
        } else {
            shipTime = templateTimeSetting.getBaseTime().intValue();
        }
        return shipTime;
    }
}
